<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>Caching and Singletons</title>

    <style type="text/css">
        <!--
        .style1 {
            font-family: "Courier New", Courier, monospace
        }

        -->
    </style>
</head>
<body>
	
<p>This is generally where a component has a single instance in the
    container that is returned to the called of getComponent(..) rather 
    than a new instance being created each time the container is asked.  
    Note that this is very different to the Singleton as 
    defined by the Gang-of-Four book 'Design Patterns' where a class has 
    a static getInstance() method and a private static instance variable.</p>

<h3>Basic Caching</h3>

<p></p>

<p>Choose your style for caching behavior:</p>

<div class="source">
<pre>pico = new DefaultPicoContainer(new Caching());
pico.addComponent(Apple.class);
Apple a1 = pico.getComponent(Apple.class);
Apple a2 = pico.getComponent(Apple.class);
// both the same instance
</pre>
</div>
<div class="source">
<pre>pico = new DefaultPicoContainer();
pico.as(CACHE).addComponent(Apple.class);
Apple a1 = pico.getComponent(Apple.class);
Apple a2 = pico.getComponent(Apple.class);
// both the same instance
</pre>
</div>
<div class="source">
<pre>pico = new PicoBuilder().withCaching().build();
pico.addComponent(Apple.class);
Apple a1 = pico.getComponent(Apple.class);
Apple a2 = pico.getComponent(Apple.class);
// both the same instance
</pre>
</div>
<div class="source">
<pre>import static org.picocontainer.behaviors.Behaviors.caching;
...
pico = new PicoBuilder().withBehaviors(caching()).build();
pico.addComponent(Apple.class);
Apple a1 = pico.getComponent(Apple.class);
Apple a2 = pico.getComponent(Apple.class);
// both the same instance
</pre>
</div>
<h3>Opt in Caching</h3>

<p>This is caching as above, but only when that property is set.</p>

<div class="source">
<pre>pico = new DefaultPicoContainer(new OptinCaching());
pico.addComponent(Apple.class);
Apple a1 = pico.getComponent(Apple.class);
Apple a2 = pico.getComponent(Apple.class);
// different instances
</pre>
</div>
<div class="source">
<pre>pico = new DefaultPicoContainer(new OptinCaching());
pico.as(CACHE).addComponent(Apple.class);
Apple a1 = pico.getComponent(Apple.class);
Apple a2 = pico.getComponent(Apple.class);
// both the same instance
</pre>
</div>
<h3>Thread Caching</h3>

<p>This is where a component has a single instance in the
    container rather that a new one created each time the container is
    asked for that type. The difference to 'Caching' is that there is one
    cache per thread using the container. For the most part you are not
    going to use this behavior unless you are 100% sure that the
    muti-threaded application you are writing maps threads to the notional
    session you are trying to model.</p>

<p>Choose your style for thread caching behavior:</p>

<div class="source">
<pre>pico = new DefaultPicoContainer(new ThreadCaching());
pico.addComponent(Apple.class);
new Thread() {
    public void run() {

        Apple a1 = pico.getComponent(Apple.class);

        Apple a2 = pico.getComponent(Apple.class);

    }
}).start();
new Thread() {
    public void run() {
        Apple a3 = pico.getComponent(Apple.class);
    }
}).start();
// a1 and a2 are the same instance
// a1 and a3 are different instances
</pre>
</div>
<div class="source">
<pre>pico = new DefaultPicoContainer();
pico.as(THREAD_CACHE).addComponent(Apple.class);

</pre>
</div>
<div class="source">
<pre>pico = new PicoBuilder().withThreadCaching().build();
pico.addComponent(Apple.class);</pre>
</div>
<h3>Storing</h3>

<p>This is where a component has a single instance in the
    container rather that a new one created each time the container is
    asked for that type. This is like 'ThreadCaching' as it has the one
    cache per thread behavior, but the whole store is can be extracted and
    set outside if you have a referene to the Storing instance. Again you
    are likely to use this behavior if you are trying to model 'session'
    behavior. With this one though you able to retrieve the cache from some
    place associated with the session and set it for the thread before use.
    After use, it can be extracted and stored back with the sesion.</p>

<p>Only one style is shown here as you will need to hang on to
    the reference to the BehaviorFactory to make use of it:</p>

<div class="source">
<pre>pico = new DefaultPicoContainer(new Storing());
pico.addComponent(Apple.class);
Apple a1, a2, a3

new Thread() {
    public void run() {

        a1 = pico.getComponent(Apple.class);

        a2 = pico.getComponent(Apple.class);

    }
}).start();
new Thread() {
    public void run() {
        a3 = pico.getComponent(Apple.class);
    }
}).start();
// a1 and a2 are the same instance
// a1 and a3 are different instances
</pre>
</div>
<p>The BehaviorFactory for Storing behavior is not stateless. It
    allows the cache to be set for the thread as well as extracted. Here's
    a code snippet to illustrate that:</p>

<div class="source">
<pre>storing = new Storing();
pico = new DefaultPicoContainer(sc);
....
storing.putCacheForThread(httpRequest.getSession().getAttribute(&quot;sessionComponentStore&quot;);
// do other methods that process request in session concept and may do getComponent(..) from the sesion container.
httpRequest.getSession().setAttribute(&quot;sessionComponentStore&quot;, sc.getCacheForThread());</pre>
</div>
<p>See <a href="scopes.html">scopes</a> for
    another example for a web framework</p>
<h3>Historical Naming thoughts</h3>
<p>The Spring Framework has traditionally had a 'Singleton Scope' for an object which is analagous.  More recently, <a href="http://code.google.com/p/google-guice/">Guice</a>
explicitly called these Singletons. After Guice came out, and given the similarities to PicoContainer, we debated this, and
decided that we should not call explicitly this a Singleton. As stated before, another PicoContainer
instance could be managing another single instance of the same component, so it does not fit the definition of Singleton given in
Design Patterns book.  It is our recommendation that teams do not call components cached in a container singletons at all. Instead we suggest you refer to them by the scope you intend. Most likely this will be 'Application Scope', 'Session scope' and 'Request Scope' for web applications, and implicitly cached at that scope for its duration.</p>
</body>
</html>